package week2.blog_code.exer1001;

import java.util.Scanner;

public class Main {

    private static int curValue = 1;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            // 读取k值
            curValue = 1;
            int k = scanner.nextInt();
            int specialRow = scanner.nextInt(); // 特殊点横坐标
            int specialCol = scanner.nextInt(); // 特殊点纵坐标
            int edges = (int) Math.pow(2, k);
            int[][] matrix = new int[edges][edges];
            matrix[specialRow][specialCol] = 0;
            partition(matrix, 0, edges - 1, 0, edges - 1, specialRow, specialCol);
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 0; j < matrix[i].length - 1; j++) {
                    System.out.printf("%4s", matrix[i][j]);
                }
                System.out.printf("%4s\n", matrix[i][matrix[i].length - 1]);
            }
        }
    }

    /**
     *
     * @param matrix 矩阵
     * @param upRow 行的上界
     * @param downRow 行的下界
     * @param leftCol 列的左边界
     * @param rightCol 列的右边界
     * @param specialRow 特殊点横坐标
     * @param specialCol 特殊点纵坐标
     */
    private static void partition(int[][] matrix, int upRow, int downRow, int leftCol, int rightCol, int specialRow, int specialCol) {
        if (upRow == downRow && leftCol == rightCol) {
            // 只有一个元素，直接返回
            return;
        }
        // 计算中心区域
        // 维护中间区域填充值
        int midValue = curValue;
        curValue++;
        int midLeftUpRow = (upRow + downRow) / 2;
        int midLeftUpCol = (leftCol + rightCol) / 2;
        if (upRow <= specialRow && specialRow <= midLeftUpRow && leftCol <= specialCol && specialCol <= midLeftUpCol) {
            // 特殊点在左上区域
            partition(matrix, upRow, midLeftUpRow, leftCol, midLeftUpCol, specialRow, specialCol);
        } else {
            matrix[midLeftUpRow][midLeftUpCol] = midValue;
            partition(matrix, upRow, midLeftUpRow, leftCol, midLeftUpCol, midLeftUpRow, midLeftUpCol);
        }
        int midRightUpRow = midLeftUpRow;
        int midRightUpCol = midLeftUpCol + 1;
        if (upRow <= specialRow && specialRow <= midRightUpRow && midRightUpCol <= specialCol && specialCol <= rightCol) {
            // 特殊点在右上区域
            partition(matrix, upRow, midRightUpRow, midRightUpCol, rightCol, specialRow, specialCol);
        } else {
            matrix[midRightUpRow][midRightUpCol] = midValue;
            partition(matrix, upRow, midRightUpRow, midRightUpCol, rightCol, midRightUpRow, midRightUpCol);
        }
        int midLeftDownRow = midLeftUpRow + 1;
        int midLeftDownCol = midLeftUpCol;
        if (midLeftDownRow <= specialRow && specialRow <= downRow && leftCol <= specialCol && specialCol <= midLeftDownCol) {
            // 特殊点在左下区域
            partition(matrix, midLeftDownRow, downRow, leftCol, midLeftDownCol, specialRow, specialCol);
        } else {
            matrix[midLeftDownRow][midLeftDownCol] = midValue;
            partition(matrix, midLeftDownRow, downRow, leftCol, midLeftDownCol, midLeftDownRow, midLeftDownCol);
        }
        int midRightDownRow = midLeftUpRow + 1;
        int midRightDownCol = midLeftUpCol + 1;
        if (midRightDownRow <= specialRow && specialRow <= downRow && midRightDownCol <= specialCol && specialCol <= rightCol) {
            // 特殊点在右下区域
            partition(matrix, midRightDownRow, downRow, midRightDownCol, rightCol, specialRow, specialCol);
        } else {
            matrix[midRightDownRow][midRightDownCol] = midValue;
            partition(matrix, midRightDownRow, downRow, midRightDownCol, rightCol, midRightDownRow, midRightDownCol);
        }
    }
}
